package joc.internal.transformer.helper;

import javassist.CannotCompileException;
import javassist.CtBehavior;
import javassist.CtField;
import javassist.expr.ExprEditor;
import javassist.expr.FieldAccess;
import javassist.expr.MethodCall;
import joc.internal.transformer.SetterTransformer;

public class SetterExpressionEditor extends ExprEditor {
	private final SetterTransformer transformer;
	private final CtField field;
	private boolean errorOccurred = false;
	private boolean assignedField = false;

	public SetterExpressionEditor(SetterTransformer transformer, CtField field) {
		this.transformer = transformer;
		this.field = field;
	}

	@Override
	public void edit(FieldAccess fieldAccess) {
		try {
			if (fieldAccess.isReader()) {
				insertError("Illegal read access in Setter on field " + fieldAccess.getFieldName() + ".",
						fieldAccess.where());
			}
			if (fieldAccess.isWriter()) {
				if (!assignedField && fieldAccess.getField().equals(field)) {
					assignedField = true;
				} else {
					insertError("Illegal write access in Setter on field " + fieldAccess.getFieldName() + ".",
							fieldAccess.where());
				}
			}
		} catch (Exception e) {
			transformer.getLogger()
					.error("Unknown exception while parsing method calls of method "
							+ fieldAccess.where().getLongName() + ".", e);
		}
	}

	@Override
	public void edit(MethodCall methodCall) {
		try {
			insertError("Illegal method access in Setter.", methodCall.where());
		} catch (CannotCompileException e) {
			transformer.getLogger().error(
					"Unknown exception while parsing method calls of method " + methodCall.where().getLongName() + ".",
					e);
		}
	}

	private void insertError(String errorMessage, CtBehavior behavior) throws CannotCompileException {
		transformer.insertError(errorMessage, behavior, !errorOccurred);
		errorOccurred = true;
	}

	public boolean isAssignedField() {
		return assignedField;
	}

	public boolean isErrorOccurred() {
		return errorOccurred;
	}
}
